package com.ldx.java_chatroom.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ldx.java_chatroom.component.OnlineUserManager;
import com.ldx.java_chatroom.mapper.MessageMapper;
import com.ldx.java_chatroom.mapper.MessageSessionMapper;
import com.ldx.java_chatroom.model.User;
import com.ldx.java_chatroom.model.WebSocketRequest;
import com.ldx.java_chatroom.model.WebSocketResponse;
import com.ldx.java_chatroom.model.item.MessageItem;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.List;

@Component
@Slf4j
public class WebSocketController extends TextWebSocketHandler {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Resource
    OnlineUserManager onlineUserManager;
    @Resource
    MessageSessionMapper messageSessionMapper;
    @Resource
    MessageMapper messageMapper;
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("[WebSocketController] 建立连接");
        User user = (User) session.getAttributes().get("User");
        if(user == null){
            return;
        }
        onlineUserManager.online(user.getUserId(), session);

    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        //System.out.println("收到请求:" + message.getPayload());
        //获取请求对象
        WebSocketRequest request = objectMapper.readValue(message.getPayload(), WebSocketRequest.class);
        //获取用户对象
        User user = (User) session.getAttributes().get("User");
        if(user == null){
            log.error("用户未登录 无法进行转发消息");
            return;
        }
        //判断消息类型 因为当前系统只支持文本 所以默认为message
        if("message".equals(request.getType())){
            transMessage(user,request);
        }else {
            log.error("消息类型错误 无法进行转发");
        }

    }

    private void transMessage(User user, WebSocketRequest request) throws IOException {
        //1.构造响应对象
        WebSocketResponse response = new WebSocketResponse();
        response.setContent(request.getContent());
        response.setType("message");
        response.setFromId(user.getUserId());
        response.setFromName(user.getUsername());
        response.setSessionId(request.getSessionId());
        //2.根据sessionId查询到用户列表挨个转发
        //此时注意 用户分为在线与不在线 在线的发送 不在线的可以通过数据库获取历史信息
        List<Integer> userIds = messageSessionMapper.getAllUsersBySessionId(request.getSessionId());
        for(int userId : userIds){
            WebSocketSession toSession = onlineUserManager.getSession(userId);
            if(toSession!=null){
                String respJson = objectMapper.writeValueAsString(response);
                log.info("转发消息为：" + respJson);
                toSession.sendMessage(new TextMessage(respJson));
            }
        }
        //3.为数据库添加一条消息记录
        MessageItem messageItem = new MessageItem();
        messageItem.setContent(request.getContent());
        messageItem.setSessionId(request.getSessionId());
        messageItem.setFromId(user.getUserId());
        messageMapper.add(messageItem);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.out.println("[WebSocketController] 异常断开");
        User user = (User) session.getAttributes().get("User");
        if(user == null){
            return;
        }
        onlineUserManager.offline(user.getUserId(),session);

    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        System.out.println("[WebSocketController] 断开连接");
        User user = (User) session.getAttributes().get("User");
        if(user == null){
            return;
        }
        onlineUserManager.offline(user.getUserId(),session);


    }
}
